package com.mjk.manager.magicapi.core.core.logging;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import com.mjk.common.core.jdbc.service.idgenerator.IdGenerateType;
import com.mjk.common.core.jdbc.service.log.model.BeeLogModel;
import com.mjk.common.core.jdbc.service.plus.idbservice.BeeDBService;
import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.tools.springextend.BeeSpringBean;
import com.mjk.common.util.ClobUtils;
import com.mjk.common.util.MDCUtils;
import com.mjk.common.util.ObjectUtils;
import io.seata.common.util.BlobUtils;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 对接Logback
 *
 * @author mxd
 */
public class LogbackLoggerContext implements MagicLoggerContext {
    public static void startLog(Map<String, Object> inparams, String type) {
        MDCUtils.initMDC();
        String sessionId = SESSION.get();
        if (ObjectUtils.isEmpty(sessionId)) {
            SESSION.set(MDCUtils.getTraceId());
        }
        // 创建一个新的 Map 用于存储非文件类型参数
        Map<String, Object> filteredParams = new HashMap<>();

        for (Map.Entry<String, Object> entry : inparams.entrySet()) {
            if (!isFileType(entry.getValue())) { // 检查是否为文件类型
                filteredParams.put(entry.getKey(), entry.getValue());
            }
        }

        Map<String, BeeLogModel> logStart = new HashedMap();
        BeeLogModel beelog = new BeeLogModel();
        beelog.setItemType(type);
        beelog.setInParams(ClobUtils.stringToClob(GsonUtils.bean2Json(filteredParams)));
        logStart.put(MDCUtils.getTraceId(), beelog);
        MagicLoggerContext.logs.set(logStart);
    }

    private static boolean isFileType(Object obj){
        return obj instanceof File || obj instanceof MultipartFile;
    }

    public static void endLog(Object outparams, String path, String group, String name) {
        BeeLogModel log = MagicLoggerContext.logs.get().get(MDCUtils.getTraceId());
        if (null != log) {
            log.setId(IdGenerateType.AUTO_SNOWFLAKE.getGenerator().getId(log));
            log.setTranceId(MDCUtils.getTraceId());
            log.setCreateTime(LocalDateTime.now());
            log.setItemId(path);
            log.setWorkName(group);
            log.setMethodName(name);
            if (ObjectUtils.isNotEmpty(outparams)) {
                if (outparams instanceof String str) {
                    log.setOutParams(ClobUtils.stringToClob(str.replaceAll("[^a-zA-Z0-9\\s\\u4e00-\\u9fa5]", "")));
                } else {
                    log.setOutParams(ClobUtils.stringToClob(GsonUtils.bean2Json(outparams)));
                }
                log.setErrorCode("1");
            }
            log.setProcessContent(ClobUtils.stringToClob(log.getTemp()));
        }
        logs.remove();
        SESSION.remove();
        BeeDBService beeDBService = BeeSpringBean.getBean(BeeDBService.class);
        beeDBService.save(log);
    }
    @Override
    public void generateAppender() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        ch.qos.logback.classic.Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME);
        MagicLogbackAppender appender = new MagicLogbackAppender();
        appender.setContext(context);
        appender.setName(LOGGER_NAME);
        appender.start();
        logger.addAppender(appender);
    }

    static class MagicLogbackAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {

        @Override
        protected void append(ILoggingEvent event) {
            Formatter formatter = Formatter.create()
                    .timestamp(event.getTimeStamp())
                    .space()
                    .level(event.getLevel().toString())
                    .value(" --- [")
                    .thread(event.getThreadName())
                    .value("] ")
                    .loggerName(event.getLoggerName())
                    .value(": ")
                    .value(event.getFormattedMessage())
                    .newline();
            IThrowableProxy proxy = event.getThrowableProxy();
            if (proxy instanceof ThrowableProxy) {
                formatter.throwable(((ThrowableProxy) proxy).getThrowable());
            }
            MagicLoggerContext.println(formatter.toString());
        }
    }
}
